package kuzha.packagemanager;
import java.io.File;
import java.io.FilenameFilter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class PackageManager {
	private PackageManager() {
		;
	}
	
	private static Set<Archive> arcs = new HashSet<Archive>();
	
	public static String[] findClassPath(String packagePath) throws PackageNotFoundException {
		String[] path = packagePath.split("\\.");
		if (0 < path.length) {
			if ("*".equals(path[path.length - 1])) {
				List<String> list = new ArrayList<String>();
				boolean exist = false;
				path = Arrays.copyOf(path, path.length - 1);
				synchronized(arcs) {
					for(Archive arc: arcs) {
						if (arc.findClass(path, list)) {
							exist = true;
						}
					}
				}
				if (exist) {
					String[] result = list.toArray(new String[list.size()]);
					String pn = kuzha.Utils.join(".", path);
					for(int i = 0; i < result.length; i++) {
						result[i] = pn + "." + result[i];
					}
					return result;
				}
			}
			else {
				return new String[] { packagePath };
			}
		}
		throw new PackageNotFoundException("package not fount: " + packagePath);
	}
	
	public static void addArchive(Archive arc) {
		synchronized (arcs) {
			if (!arcs.contains(arc)) {
				arcs.add(arc);
			}
		}
	}
	public static void addArchive(String cl, boolean subjar) {
		File file = new File(cl);
		if (file.exists()) {
			if (file.isDirectory()) {
				addArchive(new DirectoryArchive(file));
				if (subjar) {
					for (File ff: file.listFiles(new FilenameFilter(){
						@Override
						public boolean accept(File dir, String name) {
							name = name.toLowerCase();
							return name.endsWith(".jar") || name.endsWith(".zip");
						}
					})) {
						addArchive(new JarArchive(ff));
					}
				}
			}
			else {
				String name = file.getName().toLowerCase();
				if (name.endsWith(".jar") || name.endsWith(".zip")) {
					addArchive(new JarArchive(file));
				}
			}
		}
	}
	
	static {
		addClassPath(System.getProperty("sun.boot.class.path"), true);
		addClassPath(System.getProperty("java.ext.dirs"), true);
		addClassPath(System.getProperty("java.class.path"), false);
	}
	private static void addClassPath(String paths, boolean subjar) {
		if (paths != null) {
			String[] path;
			if (0 <= paths.indexOf(';'))
				path = paths.split(";");
			else if (0 <= paths.indexOf(':'))
				path = paths.split(":");
			else
				path = new String[] { paths };
			for(String cl: path)
				addArchive(cl, subjar);
		}
	}
}
